package com.stek.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Environment;
import android.os.PowerManager;
import android.os.StatFs;
import android.os.Vibrator;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.stek.R;

@SuppressWarnings("deprecation")
public class Utils {

	// =========================MOBILE DATA======================
	public static class Mobile {
		public static boolean hasTelephony(Context context) {
			if (context.getPackageManager().hasSystemFeature(
					PackageManager.FEATURE_TELEPHONY)) {
				return true;
			}

			return ConnectivityManager
					.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE);

		}

		public static void setMobileDataEnabled(Context context, boolean enabled) {
			ConnectivityManager connectivityManager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			try {
				Field mService = ConnectivityManager.class
						.getDeclaredField("mService");
				mService.setAccessible(true);
				Object iConnectivityManager = mService.get(connectivityManager);
				Class<?> iConnectivityManagerClass = Class
						.forName(iConnectivityManager.getClass().getName());
				Method setMobileDataEnabled = iConnectivityManagerClass
						.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
				setMobileDataEnabled.setAccessible(true);
				setMobileDataEnabled.invoke(iConnectivityManager, enabled);
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

		public static void toggleMobileData(Context context) {
			ConnectivityManager connectivityManager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			try {
				Field mService = ConnectivityManager.class
						.getDeclaredField("mService");
				mService.setAccessible(true);
				Object iConnectivityManager = mService.get(connectivityManager);
				Class<?> iConnectivityManagerClass = Class
						.forName(iConnectivityManager.getClass().getName());
				boolean enabled = isMobileDataEnabled(context);
				Method setMobileDataEnabled = iConnectivityManagerClass
						.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
				setMobileDataEnabled.setAccessible(true);
				setMobileDataEnabled.invoke(iConnectivityManager, !enabled);
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

		public static boolean canToggleMobileData(Context context) {
			ConnectivityManager connectivityManager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			try {
				Field mService = ConnectivityManager.class
						.getDeclaredField("mService");
				mService.setAccessible(true);
				Object iConnectivityManager = mService.get(connectivityManager);
				Class<?> iConnectivityManagerClass = Class
						.forName(iConnectivityManager.getClass().getName());
				Method getMobileDataEnabled = iConnectivityManagerClass
						.getDeclaredMethod("getMobileDataEnabled");
				getMobileDataEnabled.setAccessible(true);
				boolean enabled = (Boolean) getMobileDataEnabled
						.invoke(iConnectivityManager);
				Method setMobileDataEnabled = iConnectivityManagerClass
						.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
				setMobileDataEnabled.setAccessible(true);
				setMobileDataEnabled.invoke(iConnectivityManager, enabled);
			} catch (Exception e) {
				return false;
			}

			return true;

		}

		public static boolean isMobileDataEnabled(Context context) {
			ConnectivityManager connectivityManager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			try {
				Field mService = ConnectivityManager.class
						.getDeclaredField("mService");
				mService.setAccessible(true);
				Object iConnectivityManager = mService.get(connectivityManager);
				Class<?> iConnectivityManagerClass = Class
						.forName(iConnectivityManager.getClass().getName());
				Method getMobileDataEnabled = iConnectivityManagerClass
						.getDeclaredMethod("getMobileDataEnabled");
				getMobileDataEnabled.setAccessible(true);
				boolean enabled = (Boolean) getMobileDataEnabled
						.invoke(iConnectivityManager);
				return enabled;
			} catch (Exception e) {
				return false;
			}

		}

	}

	// =========================GPS=====================
	public static class GPS {
		public static boolean hasLocationGPS(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS);
		}

		public static boolean hasLocationNetwork(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature(PackageManager.FEATURE_LOCATION_NETWORK);
		}

		public static boolean canToggleGPS(Context context) {
			PackageManager pacman = context.getPackageManager();
			PackageInfo pacInfo = null;
			try {
				pacInfo = pacman.getPackageInfo("com.android.settings",
						PackageManager.GET_RECEIVERS);
			} catch (NameNotFoundException e) {
				return false;
			}
			if (pacInfo != null) {
				for (ActivityInfo actInfo : pacInfo.receivers) {
					if (actInfo.name
							.equals("com.android.settings.widget.SettingsAppWidgetProvider")
							&& actInfo.exported) {
						return true;
					}
				}
			}
			return false;
		}

		public static boolean isGpsEnabled(Context context) {
			LocationManager locationManager = (LocationManager) context
					.getSystemService(Context.LOCATION_SERVICE);
			return locationManager
					.isProviderEnabled(LocationManager.GPS_PROVIDER);
		}

		public static void toggleGPS(Context context) {
			if (!canToggleGPS(context)) {
				Logging.log("cannotToggleGPS");
				return;
			}
			Intent intentGPS = new Intent();
			intentGPS.setClassName("com.android.settings",
					"com.android.settings.widget.SettingsAppWidgetProvider");
			intentGPS.addCategory(Intent.CATEGORY_ALTERNATIVE);
			intentGPS.setData(Uri.parse("3"));
			context.sendBroadcast(intentGPS);
		}

		public static void setGPSEnabled(Context context, boolean enabled) {
			if (!canToggleGPS(context)) {
				return;
			}
			String provider = Settings.Secure.getString(
					context.getContentResolver(),
					Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
			if (provider.contains("gps") ^ enabled) {
				Intent intentGPS = new Intent();
				intentGPS
						.setClassName("com.android.settings",
								"com.android.settings.widget.SettingsAppWidgetProvider");
				intentGPS.addCategory(Intent.CATEGORY_ALTERNATIVE);
				intentGPS.setData(Uri.parse("3"));
				context.sendBroadcast(intentGPS);
			}
		}

	}

	/**
	 * BRIGHTNESS
	 */
	// ===================================================================================================
	public static void setAutoBrightMode(Context context, boolean isAuto) {
		Settings.System.putInt(context.getContentResolver(),
				Settings.System.SCREEN_BRIGHTNESS_MODE,
				isAuto ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
						: Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
	}

	/**
	 * @param brightness
	 *            : 0 - 255
	 */
	public static void setBrightness(Context context, int brightness) {
		if (brightness < 0) {
			return;
		}
		setAutoBrightMode(context, false);
		Settings.System.putInt(context.getContentResolver(),
				Settings.System.SCREEN_BRIGHTNESS, brightness);
	}

	public static int getBrightness(Context context) {
		try {
			return Settings.System.getInt(context.getContentResolver(),
					Settings.System.SCREEN_BRIGHTNESS);
		} catch (SettingNotFoundException e) {
			return -1;
		}
	}

	public static int getBrightnessMode(Context context) {
		try {
			return Settings.System.getInt(context.getContentResolver(),
					Settings.System.SCREEN_BRIGHTNESS_MODE);
		} catch (SettingNotFoundException e) {
			return -1;
		}
	}

	// =========================WIFI=====================
	public static class WIFI {
		public static class WifiInfo {
			public String SSID;
			public String BSSID;

			@Override
			public boolean equals(Object o) {
				// TODO Auto-generated method stub

				return SSID.equals(((WifiInfo) o).SSID)
						&& BSSID.equals(((WifiInfo) o).BSSID);
			}
		}

		public static ArrayList<WifiInfo> getAvailableWifi(Context context) {
			ArrayList<WifiInfo> infos = new ArrayList<Utils.WIFI.WifiInfo>();
			WifiManager wifiManager = (WifiManager) context
					.getSystemService(Context.WIFI_SERVICE);
			List<ScanResult> results = wifiManager.getScanResults();
			for (ScanResult scanResult : results) {
				WifiInfo info = new WifiInfo();
				info.BSSID = scanResult.BSSID;
				info.SSID = scanResult.SSID;
				infos.add(info);
			}
			return infos;
		}

		public static boolean hasWifi(Context context) {
			if (ConnectivityManager
					.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI)) {
				return true;
			}
			return context.getPackageManager().hasSystemFeature(
					PackageManager.FEATURE_WIFI);
		}

		public static boolean hasWifiDirect(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature("android.hardware.wifi.direct");
		}

		public static boolean isWifiEnabled(Context context) {
			WifiManager wifiManager = (WifiManager) context
					.getSystemService(Context.WIFI_SERVICE);
			int wifiState = wifiManager.getWifiState();
			return wifiState == WifiManager.WIFI_STATE_ENABLED;
		}

		public static boolean setWifiEnabled(Context context, boolean enabled) {
			WifiManager wifiManager = (WifiManager) context
					.getSystemService(Context.WIFI_SERVICE);
			return wifiManager.setWifiEnabled(enabled);
		}

		public static void toggleWifi(Context context) {
			WifiManager wifiManager = (WifiManager) context
					.getSystemService(Context.WIFI_SERVICE);
			wifiManager.setWifiEnabled(!isWifiEnabled(context));
		}

		public static NetworkInfo getConnectedWifi(Context context) {
			ConnectivityManager connManager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo networkInfo = connManager
					.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
			return networkInfo.isConnected() ? networkInfo : null;

		}

		public static String getCurrentBSSID(Context context) {
			String bssid = null;
			ConnectivityManager connManager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo networkInfo = connManager
					.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
			if (networkInfo.isConnected()) {
				final WifiManager wifiManager = (WifiManager) context
						.getSystemService(Context.WIFI_SERVICE);
				final android.net.wifi.WifiInfo connectionInfo = wifiManager
						.getConnectionInfo();
				if (connectionInfo != null
						&& !TextUtils.isEmpty(connectionInfo.getBSSID())) {
					bssid = connectionInfo.getBSSID();
				}
			}
			return bssid;
		}

		public static boolean isConnected(Context context) {
			ConnectivityManager connManager = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo wifi = connManager
					.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
			return wifi.isConnected();
		}

	}

	// =============================BLUETOOTH============================
	public static class Bluetooth {

		public static boolean hasBluetooth(Context context) {
			if (context.getPackageManager().hasSystemFeature(
					PackageManager.FEATURE_BLUETOOTH)) {
				return true;
			}
			return BluetoothAdapter.getDefaultAdapter() != null;
		}

		public static boolean hasBluetoothLE(Context context) {
			if (context.getPackageManager().hasSystemFeature(
					PackageManager.FEATURE_BLUETOOTH_LE)) {
				return true;
			}
			return BluetoothAdapter.getDefaultAdapter() != null;
		}

		public static boolean isBluetoothEnabled(Context context) {
			if (!hasBluetooth(context)) {
				return false;
			}
			BluetoothAdapter bluetoothAdapter = BluetoothAdapter
					.getDefaultAdapter();

			return bluetoothAdapter.isEnabled();
		}

		public static boolean setBluetoothEnabled(Context context,
				boolean enabled) {
			if (!hasBluetooth(context)) {
				return false;
			}
			BluetoothAdapter bluetoothAdapter = BluetoothAdapter
					.getDefaultAdapter();
			return enabled ? bluetoothAdapter.enable() : bluetoothAdapter
					.disable();

		}

		public static void toggleBluetoothEnabled(Context context) {
			if (!hasBluetooth(context)) {
				return;
			}
			setBluetoothEnabled(context, !isBluetoothEnabled(context));

		}

	}

	// =============================AIRPLANE MODE============================
	public static class Airplane {
		@SuppressLint("NewApi")
		public static boolean isAirPlaneModeEnable(Context context) {
			int sdk = Build.VERSION.SDK_INT;
			if (sdk < 17) {
				return Settings.System.getInt(context.getContentResolver(),
						Settings.System.AIRPLANE_MODE_ON, 0) != 0;

			}
			return Settings.Global.getInt(context.getContentResolver(),
					Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
		}

		@SuppressLint("NewApi")
		public static void setAirPlaneModeEnable(Context context,
				boolean enabled) {
			try {
				int sdk = Build.VERSION.SDK_INT;
				if (sdk < Build.VERSION_CODES.JELLY_BEAN_MR1) {
					// Change the system setting
					Settings.System.putInt(context.getContentResolver(),
							Settings.System.AIRPLANE_MODE_ON, enabled ? 1 : 0);

				} else {
					// Change the system setting
					Settings.Global.putInt(context.getContentResolver(),
							Settings.Global.AIRPLANE_MODE_ON, enabled ? 1 : 0);

				}
				// Post the intent
				Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
				intent.putExtra("state", enabled);
				context.sendBroadcast(intent);

			} catch (Exception e) {
				AppUtils.launchWirelessSettings(context);
			}

		}

		public static void toggleAirPlaneMode(Context context) {
			setAirPlaneModeEnable(context, !isAirPlaneModeEnable(context));
		}

	}

	/**
	 * RING MODE
	 */
	// ===================================================================================================
	@SuppressLint("NewApi")
	public static boolean isVibrateSupported(Context context) {
		Vibrator vibrator = (Vibrator) context
				.getSystemService(Context.VIBRATOR_SERVICE);
		if (Build.VERSION.SDK_INT < 11) {
			return (vibrator == null);
		}
		return (vibrator == null || !vibrator.hasVibrator());
	}

	public static int getSoundMode(Context context) {
		AudioManager am = (AudioManager) context
				.getSystemService(Context.AUDIO_SERVICE);
		return am.getRingerMode();

	}

	public static void setSoundMode(Context context, int ringerMode) {
		AudioManager am = (AudioManager) context
				.getSystemService(Context.AUDIO_SERVICE);
		am.setRingerMode(ringerMode);
	}

	public static void switchSoundMode(Context context) {
		AudioManager am = (AudioManager) context
				.getSystemService(Context.AUDIO_SERVICE);
		if (isVibrateSupported(context)) {
			am.setRingerMode((getSoundMode(context) + 1) % 3);
		} else {
			am.setRingerMode((getSoundMode(context) + 2) % 3);
		}

	}

	// =============================CAMERA============================
	public static class CameraHardware {
		public static int getNumberCamera() {
			return Camera.getNumberOfCameras();

		}

		public static boolean hasCameraBack(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature(PackageManager.FEATURE_CAMERA);
		}

		public static boolean hasCameraFront(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
		}

		public static boolean hasCameraFlash(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
		}

		public static boolean hasTorch(Context context) {
			Camera camera = getBackCamera();
			if (null == camera) {
				return false;
			}
			Parameters parameters = camera.getParameters();
			try {
				if (parameters.getFlashMode().contains(
						Parameters.FLASH_MODE_TORCH)) {
					camera.release();
					return true;
				}
			} catch (Exception e) {
				camera.release();
				return false;
			}
			camera.release();
			PackageManager packageManager = context.getPackageManager();
			boolean isFlash = packageManager
					.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
			if (isFlash) {
				return isFlash;
			}

			return false;
		}

		public static boolean hasCameraAutoFocus(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
		}

		public static Camera getBackCamera() {
			int cameraCount = 0;
			Camera camera = null;
			Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
			cameraCount = Camera.getNumberOfCameras();
			for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
				Camera.getCameraInfo(camIdx, cameraInfo);
				if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
					try {
						camera = Camera.open(camIdx);
					} catch (RuntimeException e) {
						// Camera is not available (in use or does not exist)
					}
				}
			}
			return camera;
		}

		public static Camera getFrontCamera() {
			int cameraCount = 0;
			Camera camera = null;
			Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
			cameraCount = Camera.getNumberOfCameras();
			for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
				Camera.getCameraInfo(camIdx, cameraInfo);
				if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
					try {
						camera = Camera.open(camIdx);
					} catch (RuntimeException e) {
						// Camera is not available (in use or does not exist)
					}
				}
			}
			return camera;
		}

		public static void setFlashEnabled(Context context, Camera camera,
				boolean enabled) {
			Parameters parameters = camera.getParameters();
			try {
				parameters.setFlashMode(enabled ? Parameters.FLASH_MODE_TORCH
						: Parameters.FLASH_MODE_OFF);
				camera.autoFocus(new AutoFocusCallback() {

					@Override
					public void onAutoFocus(boolean success, Camera camera) {
						// TODO Auto-generated method stub

					}
				});
			} catch (Exception e) {
				// TODO: handle exception
			}

			camera.setParameters(parameters);
			if (enabled) {
				camera.startPreview();
			} else {
				camera.stopPreview();
			}
		}

		public static void releaseCamera(Camera camera) {
			if (camera != null) {
				camera.release();
				camera = null;
			}

		}

		public static boolean hasZoom(Camera camera) {
			Camera.Parameters parameters = camera.getParameters();
			boolean hasZoom = parameters.isZoomSupported();
			// releaseCamera(camera);
			return hasZoom;
		}

		public static int getMaxZoom(Camera camera) {
			Camera.Parameters parameters = camera.getParameters();
			int maxZoom = parameters.getMaxZoom();
			// releaseCamera(camera);
			return maxZoom;
		}

		public static String getCameraResolutionInMP(Camera camera) {
			Camera.Parameters parameters = camera.getParameters();
			List<Size> sizes = parameters.getSupportedPictureSizes();
			List<Integer> widths = new ArrayList<Integer>();
			List<Integer> heights = new ArrayList<Integer>();
			for (Size size : sizes) {
				widths.add(size.width);
				heights.add(size.height);
			}
			int maxW = 0;
			int maxH = 0;
			maxW = Collections.max(widths);
			maxH = Collections.max(heights);
			double megapixel = maxH * maxW / (1000 * 1000 * 1.0f);
			// releaseCamera(camera);
			return String.format(Locale.ENGLISH, "%.1f MP", megapixel);
		}

		@SuppressLint("NewApi")
		public static String getVideoResolution(Context context, Camera camera) {
			if (Build.VERSION.SDK_INT < 11) {
				return "Yes";
			}
			Camera.Parameters parameters = camera.getParameters();
			List<Size> sizes = parameters.getSupportedVideoSizes();
			List<Integer> widths = new ArrayList<Integer>();
			List<Integer> heights = new ArrayList<Integer>();
			if (sizes == null || sizes.size() == 0) {
				return context.getString(R.string.n_a);
			}
			for (Size size : sizes) {
				widths.add(size.width);
				heights.add(size.height);
			}

			int maxW = 0;
			int maxH = 0;
			maxW = Collections.max(widths);
			maxH = Collections.max(heights);
			// releaseCamera(camera);
			return String.format(Locale.ENGLISH, "%d x %d", maxW, maxH);
		}

	}

	/**
	 * POWER
	 */
	// ===================================================================================================
	public static void powerReboot(Context context) {
		PowerManager powerManager = (PowerManager) context
				.getSystemService(Context.POWER_SERVICE);
		Class<?> powerManagerClass = powerManager.getClass();
		try {
			Field mService = powerManagerClass.getDeclaredField("mService");
			mService.setAccessible(true);
			Object iPowerManagerObject = mService.get(powerManager);
			Class<?> iPowerManagerClass = Class.forName(iPowerManagerObject
					.getClass().getName());
			Method reboot = iPowerManagerClass.getDeclaredMethod("reboot",
					boolean.class, String.class, boolean.class);
			reboot.setAccessible(true);
			// reboot(boolean confirm, java.lang.String reason, boolean wait)
			reboot.invoke(iPowerManagerObject, false, "reboot", true);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	// =============================ROTATION============================
	public static class Rotation {
		public static boolean isAutoOrientationEnabled(Context context) {
			return Settings.System.getInt(context.getContentResolver(),
					Settings.System.ACCELEROMETER_ROTATION, 0) == 1;
		}

		public static void setAutoOrientationEnabled(Context context,
				boolean enabled) {
			Settings.System.putInt(context.getContentResolver(),
					Settings.System.ACCELEROMETER_ROTATION, enabled ? 1 : 0);
		}

		public static void toggleAutoOrientation(Context context) {
			Settings.System.putInt(context.getContentResolver(),
					Settings.System.ACCELEROMETER_ROTATION,
					isAutoOrientationEnabled(context) ? 0 : 1);
		}

	}

	// =============================BATTERY============================
	public static class Battery {
		public static int getRemainBattery(Context context) {
			Intent intent = context.registerReceiver(null, new IntentFilter(
					Intent.ACTION_BATTERY_CHANGED));
			int current = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100);
			int max = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
			return current * 100 / max;

		}

		public static int getBatteryHeat(Context context) {
			Intent intent = context.registerReceiver(null, new IntentFilter(
					Intent.ACTION_BATTERY_CHANGED));
			return intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 100);
		}

		public static int getBatteryVoltage(Context context) {
			Intent intent = context.registerReceiver(null, new IntentFilter(
					Intent.ACTION_BATTERY_CHANGED));
			return intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 100);
		}

		public static String getBatteryStatus(Resources res,
				Intent batteryChangedIntent) {
			final Intent intent = batteryChangedIntent;

			int plugType = intent.getIntExtra("plugged", 0);
			int status = intent.getIntExtra("status",
					BatteryManager.BATTERY_STATUS_UNKNOWN);
			String statusString;
			if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
				statusString = "Charging";
				if (plugType > 0) {
					statusString = statusString
							+ " "
							+ ((plugType == BatteryManager.BATTERY_PLUGGED_AC) ? "(AC)"
									: "(USB)");
				}
			} else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
				statusString = "Discharging";
			} else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
				statusString = "Not charging";
			} else if (status == BatteryManager.BATTERY_STATUS_FULL) {
				statusString = "Full";
			} else {
				statusString = "Unknown";
			}

			return statusString;
		}

		public static double getBatteryCapacity(Context context) {
			Object mPowerProfile_ = null;

			final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile";

			try {
				mPowerProfile_ = Class.forName(POWER_PROFILE_CLASS)
						.getConstructor(Context.class).newInstance(context);
			} catch (Exception e) {
				e.printStackTrace();
			}

			try {
				double batteryCapacity = (Double) Class
						.forName(POWER_PROFILE_CLASS)
						.getMethod("getAveragePower", java.lang.String.class)
						.invoke(mPowerProfile_, "battery.capacity");
				return batteryCapacity;
			} catch (Exception e) {
				return -1;
			}
		}

	}

	/**
	 * LOCK SCREEN
	 */
	// ===================================================================================================
	@SuppressLint("NewApi")
	public static boolean isLockscreenSecured(Context context) {
		KeyguardManager mm = (KeyguardManager) context
				.getSystemService(Context.KEYGUARD_SERVICE);
		boolean secured = false;

		if (Build.VERSION.SDK_INT >= 16) {
			secured |= mm.isKeyguardSecure();
		}

		secured |= mm.inKeyguardRestrictedInputMode();
		secured |= android.provider.Settings.System.getInt(
				context.getContentResolver(),
				Settings.Secure.LOCK_PATTERN_ENABLED, 0) > 0;

		return secured;
	}

	public static void disableLockScreen(Context context) {
		KeyguardManager keyguardManager = (KeyguardManager) context
				.getSystemService(Activity.KEYGUARD_SERVICE);
		KeyguardLock lock = keyguardManager
				.newKeyguardLock(Context.KEYGUARD_SERVICE);
		lock.disableKeyguard();
	}

	// =============================CPU============================
	public static class CPU {
		private static final String CPU_INFO_FILE = "/proc/cpuinfo";
		private static final String CPU_CORE_FILE = "/sys/devices/system/cpu/possible";
		private static final String CPU_FREQ_FILE = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq";

		public static String getCPUName() {
			String name = "N/A";
			BufferedReader in = null;
			try {
				in = new BufferedReader(new FileReader(CPU_INFO_FILE));
				String line;
				while ((line = in.readLine()) != null) {
					if (line.startsWith("Processor")) {
						name = line.substring(line.indexOf(":") + 1);
						break;
					} else if (line.startsWith("model name")) {
						name = line.substring(line.indexOf(":") + 1);
						break;
					}
				}
				in.close();
			} catch (IOException e) {
			}

			return name;
		}

		public static int getNumberCPUs() {
			return Runtime.getRuntime().availableProcessors();
		}

		public static int getNumberCores() {
			int cores = 0;
			BufferedReader in = null;
			try {
				in = new BufferedReader(new FileReader(CPU_CORE_FILE));
				String str = in.readLine();
				if (str != null && str.length() > 0) {
					int index = str.indexOf("-");
					if (index != -1) {
						StringTokenizer sTok = new StringTokenizer(str, "-",
								false);
						for (; sTok.hasMoreTokens();) {
							try {
								Integer.parseInt(sTok.nextToken());
								cores++;
							} catch (NumberFormatException nfe) {
							}
						}
					} else {
						try {
							Integer.parseInt(str);
							cores = 1;
						} catch (NumberFormatException nfe) {
						}
					}
				}
				in.close();
			} catch (IOException e) {
				return cores;
			} finally {
				if (in != null)
					try {
						in.close();
					} catch (IOException e) {
					}
			}
			return cores;
		}

		public static String getCPUFrequency(Context context) {
			StringBuffer buff = new StringBuffer();
			BufferedReader in = null;
			try {
				in = new BufferedReader(new FileReader(CPU_FREQ_FILE));
				String str;
				while ((str = in.readLine()) != null) {
					buff.append(str);
				}
				in.close();
			} catch (IOException e) {
			} finally {
				if (in != null)
					try {
						in.close();
					} catch (IOException e) {
					}
			}
			try {
				Double freq = Double.valueOf(buff.toString());
				freq = freq / 1000;
				return freq.toString();
			} catch (Exception e) {
				return context.getString(R.string.n_a);
			}
		}

		public static String getCPUManufacture() {
			String manufacture = "N/A";
			try {
				BufferedReader reader = new BufferedReader(new FileReader(
						new File(CPU_INFO_FILE)));
				String line;
				while ((line = reader.readLine()) != null) {
					if (line.startsWith("CPU implementer")) {
						int code = Integer.parseInt(
								line.substring(line.indexOf(":") + 1), 16);
						switch (code) {
						case 0x41:
							manufacture = "ARM Limited";
							break;
						case 0x44:
							manufacture = "Digital Equipment Corporation";
							break;
						case 0x4D:
							manufacture = "Motorola, Freescale Semiconductor Inc.";
							break;
						case 0x51:
							manufacture = "QUALCOMM Inc.";
							break;
						case 0x56:
							manufacture = "Marvell Semiconductor Inc.";
							break;
						case 0x69:
							manufacture = "Intel Corporation";
							break;

						default:
							manufacture = "N/A";
							break;
						}
					}

				}
				reader.close();
			} catch (Exception e) {

			}
			return manufacture;

		}

		public static String getOPENGLVersion(Context context) {
			ActivityManager activityManager = (ActivityManager) context
					.getSystemService(Context.ACTIVITY_SERVICE);
			ConfigurationInfo configurationInfo = activityManager
					.getDeviceConfigurationInfo();
			return configurationInfo.getGlEsVersion();
		}
	}

	// =============================HARDWARE============================
	public static class Hardware {

		public static int getNumberOfCPUs() {
			return Runtime.getRuntime().availableProcessors();
		}

		public static class CPUInfo {
			public String modelName;
			public String cores;
			public String clock;
			public String cpus;
		}

		public static CPUInfo readCPUInfo(Context context) {
			File file = new File("/proc/cpuinfo");
			file.setReadable(true);
			CPUInfo cpuInfo = new CPUInfo();
			cpuInfo.cpus = String.valueOf(Runtime.getRuntime()
					.availableProcessors());
			if (!file.exists()) {
				return cpuInfo;
			}
			try {
				BufferedReader reader = new BufferedReader(new FileReader(file));
				String line;
				while ((line = reader.readLine()) != null) {
					if (line.contains("model name")) {
						cpuInfo.modelName = line
								.substring(line.indexOf(":") + 1);
					} else if (line.contains("cpu cores")) {
						cpuInfo.cores = line.substring(line.indexOf(":") + 1);
					} else if (line.contains("cpu MHz")) {
						cpuInfo.clock = line.substring(line.indexOf(":") + 1);
					}

				}
				reader.close();
			} catch (Exception e) {

			}
			return cpuInfo;
		}

		public static class GPUInfo {
			public String vendor;
			public String version;
		}

		public static void getGPUInfo(Context context, final GPUInfo info) {
			GLSurfaceView glSurfaceView = new GLSurfaceView(context);
			glSurfaceView.setRenderer(new Renderer() {

				@Override
				public void onSurfaceCreated(GL10 gl, EGLConfig config) {
					info.vendor = gl.glGetString(GL10.GL_VENDOR);
					info.version = gl.glGetString(GL10.GL_VERSION);
				}

				@Override
				public void onSurfaceChanged(GL10 gl, int width, int height) {
					// TODO Auto-generated method stub

				}

				@Override
				public void onDrawFrame(GL10 gl) {
					// TODO Auto-generated method stub

				}
			});
		}

		public static int getNetworkType(Context context) {
			TelephonyManager telephonyManager = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);
			int network = telephonyManager.getNetworkType();
			return network;
		}

		/**
		 * @param name
		 *            : get from
		 *            http://developer.android.com/reference/android/content
		 *            /pm/PackageManager.html
		 */
		public static boolean hasHardwareFeature(Context context, String name) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager.hasSystemFeature(name);
		}

		public static boolean hasMicrophone(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature(PackageManager.FEATURE_MICROPHONE);
		}

		public static boolean hasNFC(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager.hasSystemFeature(PackageManager.FEATURE_NFC);
		}

		/**
		 * @param name
		 *            : get from PackageManager.java
		 */
		public static boolean hasSensor(Context context, String name) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager.hasSystemFeature(name);
		}

		public static boolean hasTelevision(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature("android.hardware.type.television");
		}

		public static boolean hasMultiTouch(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH);
		}

		@SuppressLint("NewApi")
		public static boolean hasVibrate(Context context) {
			Vibrator vibrator = (Vibrator) context
					.getSystemService(Context.VIBRATOR_SERVICE);
			if (Build.VERSION.SDK_INT < 11) {
				return (vibrator != null);
			}
			return (vibrator != null && vibrator.hasVibrator());

		}

		public static boolean hasUSB(Context context) {
			PackageManager packageManager = context.getPackageManager();
			return packageManager
					.hasSystemFeature("android.hardware.usb.accessory")
					|| packageManager
							.hasSystemFeature("android.hardware.usb.host");
		}

		public static ArrayList<String> getAllSensorString(Context context) {
			ArrayList<String> sensorString = new ArrayList<String>();
			SensorManager sensorManager = (SensorManager) context
					.getSystemService(Context.SENSOR_SERVICE);
			List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
			for (Sensor sensor : sensors) {
				sensorString.add(sensor.getName());
				Logging.log(sensor.getName());
			}
			return sensorString;
		}

		public static List<Sensor> getAllSensors(Context context) {
			SensorManager sensorManager = (SensorManager) context
					.getSystemService(Context.SENSOR_SERVICE);
			return sensorManager.getSensorList(Sensor.TYPE_ALL);

		}

		public static String getOPENGLVersion(Context context) {
			ActivityManager activityManager = (ActivityManager) context
					.getSystemService(Context.ACTIVITY_SERVICE);
			ConfigurationInfo configurationInfo = activityManager
					.getDeviceConfigurationInfo();
			return configurationInfo.getGlEsVersion();
		}

		public static String getUID(Context context) {
			TelephonyManager mTeleMan = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);
			String UID = mTeleMan.getDeviceId();

			if (TextUtils.isEmpty(UID)) {
				WifiManager manager = (WifiManager) context
						.getSystemService(Context.WIFI_SERVICE);
				WifiInfo info = manager.getConnectionInfo();

				UID = info.getMacAddress();
			}

			return TextUtils.isEmpty(UID) ? "<Unknown>" : UID;
		}

		public static boolean hasSDCard() {
			return android.os.Environment.getExternalStorageState().equals(
					android.os.Environment.MEDIA_MOUNTED);
		}

		/**
		 * Helper method to determine if the device has an extra-large screen.
		 * For example, 10" tablets are extra-large.
		 */
		public static boolean isXLargeTablet(Context context) {
			return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
		}

		public static boolean isLandcapse(Context context) {
			return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;

		}
	}

	// =============================MEMORY============================
	public static class Memory {
		@SuppressLint("NewApi")
		public static long getTotalMemory(Context context) {
			if (Build.VERSION.SDK_INT < 16) {

				File file = new File("/proc/meminfo");
				if (!file.exists()) {
					return 0;
				}
				try {
					FileReader reader = new FileReader(file);
					BufferedReader bufferedReader = new BufferedReader(reader);
					String total;
					while ((total = bufferedReader.readLine()) != null) {
						if (total.startsWith("MemTotal")) {
							break;
						}
					}
					bufferedReader.close();
					if (TextUtils.isEmpty(total)) {
						return 0;
					}
					total = total.replaceAll("[^0-9]", "");
					return Long.valueOf(total);
				} catch (Exception e) {
					return 0;
				}

			} else {
				ActivityManager actManager = (ActivityManager) context
						.getSystemService(Context.ACTIVITY_SERVICE);
				MemoryInfo memInfo = new ActivityManager.MemoryInfo();
				actManager.getMemoryInfo(memInfo);
				return memInfo.totalMem;
			}

		}

		public static long getAvailableMemory(Context context) {
			ActivityManager actManager = (ActivityManager) context
					.getSystemService(Context.ACTIVITY_SERVICE);
			MemoryInfo memInfo = new ActivityManager.MemoryInfo();
			actManager.getMemoryInfo(memInfo);
			return memInfo.availMem;

		}

		public static long getTotalMemoryBeforeAPI16(Context context) {
			File file = new File("/proc/meminfo");
			if (!file.exists()) {
				return 0;
			}
			try {
				FileReader reader = new FileReader(file);
				BufferedReader bufferedReader = new BufferedReader(reader);
				String total = bufferedReader.readLine();
				bufferedReader.close();
				if (TextUtils.isEmpty(total)) {
					return 0;
				}
				total = total.replaceAll("[^0-9]", "");
				return Long.valueOf(total);
			} catch (Exception e) {
				return 0;
			}

		}

		public static MemoryInfo getMemoryInfo(Context context) {
			ActivityManager actManager = (ActivityManager) context
					.getSystemService(Context.ACTIVITY_SERVICE);
			MemoryInfo memInfo = new ActivityManager.MemoryInfo();
			actManager.getMemoryInfo(memInfo);
			return memInfo;
		}

		public static boolean isExternalMemoryAvailable() {
			return android.os.Environment.getExternalStorageState().equals(
					android.os.Environment.MEDIA_MOUNTED);
		}

		public static long getAvailableExternalMemorySize() {
			if (isExternalMemoryAvailable()) {
				File path = Environment.getExternalStorageDirectory();
				StatFs stat = new StatFs(path.getAbsolutePath());
				long blockSize = stat.getBlockSize();
				long availableBlocks = stat.getAvailableBlocks();
				return availableBlocks * blockSize;
			} else {
				return -1;
			}
		}

		public static long getTotalExternalMemorySize() {
			if (isExternalMemoryAvailable()) {
				File path = Environment.getExternalStorageDirectory();
				StatFs stat = new StatFs(path.getPath());
				long blockSize = stat.getBlockSize();
				long totalBlocks = stat.getBlockCount();
				return totalBlocks * blockSize;
			} else {
				return -1;
			}
		}

		public static long getAvailableInternalMemorySize() {
			File path = Environment.getDataDirectory();
			StatFs stat = new StatFs(path.getPath());
			long blockSize = stat.getBlockSize();
			long availableBlocks = stat.getAvailableBlocks();
			return availableBlocks * blockSize;
		}

		public static long getTotalInternalMemorySize() {
			File path = Environment.getDataDirectory();
			StatFs stat = new StatFs(path.getPath());
			long blockSize = stat.getBlockSize();
			long totalBlocks = stat.getBlockCount();
			return totalBlocks * blockSize;
		}

	}

	// =============================SCREEN============================
	public static class Screen {
		public String getTouchScreenType(Context context) {
			String touchType = context.getString(R.string.n_a);
			ActivityManager am = (ActivityManager) context
					.getSystemService(Context.ACTIVITY_SERVICE);
			ConfigurationInfo info = am.getDeviceConfigurationInfo();
			switch (info.reqTouchScreen) {
			case Configuration.TOUCHSCREEN_FINGER:
				touchType = "Finger";
				break;
			case Configuration.TOUCHSCREEN_STYLUS:
				touchType = "Stylus";
				break;
			case Configuration.TOUCHSCREEN_NOTOUCH:
			case Configuration.TOUCHSCREEN_UNDEFINED:
				touchType = context.getString(R.string.n_a);
				break;
			default:
				break;
			}
			return touchType;
		}

		@SuppressLint("NewApi")
		public static Point getScreenSize(Context context) {
			Point point = new Point();
			WindowManager windowManager = (WindowManager) context
					.getSystemService(Context.WINDOW_SERVICE);
			Display display = windowManager.getDefaultDisplay();
			if (Build.VERSION.SDK_INT < 13) {
				point.x = display.getWidth();
				point.y = display.getHeight();
			} else {
				display.getSize(point);
			}
			return point;
		}

		public static float getRefreshRate(Context context) {
			WindowManager windowManager = (WindowManager) context
					.getSystemService(Context.WINDOW_SERVICE);
			Display display = windowManager.getDefaultDisplay();
			return display.getRefreshRate();
		}

		public static class ScreenInfo {
			public int width;
			public int height;
			public int densityDpi;
			public double inches;
		}

		@SuppressLint("NewApi")
		public static ScreenInfo getScreenInfo(Context context) {
			ScreenInfo screenInfo = new ScreenInfo();
			WindowManager windowManager = (WindowManager) context
					.getSystemService(Context.WINDOW_SERVICE);
			Display display = windowManager.getDefaultDisplay();
			if (Build.VERSION.SDK_INT < 13) {
				screenInfo.width = display.getWidth();
				screenInfo.height = display.getHeight();
			} else {
				Point point = new Point();
				display.getSize(point);
				screenInfo.width = point.x;
				screenInfo.height = point.y;
			}
			DisplayMetrics metrics = context.getResources().getDisplayMetrics();
			screenInfo.densityDpi = metrics.densityDpi;
			double x = screenInfo.width / metrics.xdpi;
			double y = screenInfo.height / metrics.ydpi;
			screenInfo.inches = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
			screenInfo.inches = (double) (((int) (screenInfo.inches * 10)) / 10.0f);
			return screenInfo;
		}

	}

	// =============================SIM============================

	public static class Telephony {
		public static boolean hasTelephony(Context context) {
			if (!context.getPackageManager().hasSystemFeature(
					PackageManager.FEATURE_TELEPHONY)) {
				return false;
			}
			TelephonyManager telephonyManager = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);
			if (telephonyManager.getDeviceId() == null) {
				return false;
			}
			return true;

		}

		public static String getPhoneType(Context context) {
			if (!hasTelephony(context)) {
				return context.getString(R.string.n_a);
			}
			TelephonyManager telephonyManager = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);
			int network2G = telephonyManager.getPhoneType();
			switch (network2G) {
			case TelephonyManager.PHONE_TYPE_CDMA:
				return "CDMA";
			case TelephonyManager.PHONE_TYPE_GSM:
				return "GSM";
			case TelephonyManager.PHONE_TYPE_SIP:
				return "SIP";
			case TelephonyManager.PHONE_TYPE_NONE:
				return "None";
			default:
				return "Unknown";
			}
		}

		public static String getNetworkType(Context context) {
			if (!hasTelephony(context)) {
				return context.getString(R.string.n_a);
			}
			TelephonyManager telephonyManager = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);
			int network3G = telephonyManager.getNetworkType();
			switch (network3G) {
			case TelephonyManager.NETWORK_TYPE_GPRS:
				return "GPRS";
			case TelephonyManager.NETWORK_TYPE_EDGE:
				return "EDGE";
			case TelephonyManager.NETWORK_TYPE_UMTS:
				return "UMTS";
			case TelephonyManager.NETWORK_TYPE_HSPAP: // NETWORK_TYPE_HSDPA
				return "HSPAP";
			case TelephonyManager.NETWORK_TYPE_HSUPA: // NETWORK_TYPE_HSUPA
				return "HSUPA";
			case TelephonyManager.NETWORK_TYPE_HSPA: // NETWORK_TYPE_HSPA
				return "HSPA";
			case TelephonyManager.NETWORK_TYPE_CDMA: // NETWORK_TYPE_CDMA
				return "CDMA";
			case TelephonyManager.NETWORK_TYPE_EVDO_0: // NETWORK_TYPE_EVDO_0
				return "EVDO_0";
			case TelephonyManager.NETWORK_TYPE_EVDO_A: // NETWORK_TYPE_EVDO_A
				return "EVDO_A";
			case TelephonyManager.NETWORK_TYPE_EVDO_B: // NETWORK_TYPE_EVDO_B
				return "EVDO_B";
			case TelephonyManager.NETWORK_TYPE_1xRTT: // NETWORK_TYPE_1xRTT
				return "TYPE_1xRTT";
			case TelephonyManager.NETWORK_TYPE_IDEN: // NETWORK_TYPE_IDEN
				return "IDEN";
			case TelephonyManager.NETWORK_TYPE_LTE: // NETWORK_TYPE_LTE (since
													// API Level 11)
				return "LTE";
			case TelephonyManager.NETWORK_TYPE_EHRPD: // NETWORK_TYPE_LTE (since
				// API Level 11)
				return "EHRPD";
			case TelephonyManager.NETWORK_TYPE_HSDPA: // NETWORK_TYPE_LTE (since
				// API Level 11)
				return "HSDPA";
			case TelephonyManager.NETWORK_TYPE_UNKNOWN:
				return context.getString(R.string.n_a);
			default:
				break;
			}
			return context.getString(R.string.n_a);
		}

		public static SimInfo getSIM1(Context context) {
			TelephonyManager telephonyManager = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);
			SimInfo sim = new SimInfo();
			sim.serial = telephonyManager.getSimSerialNumber();
			sim.number = telephonyManager.getLine1Number();
			sim.deviceId = telephonyManager.getDeviceId();
			return sim;
		}

		public static SimInfo getSIM2(Context context) {
			TelephonyManager telephonyManager = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);
			SimInfo sim = new SimInfo();
			Class<?> telephonyManagerClass = TelephonyManager.class;

			try {
				Method getSimSerialNumberGemini = telephonyManagerClass
						.getDeclaredMethod("getSimSerialNumberGemini",
								Integer.TYPE);
				getSimSerialNumberGemini.setAccessible(true);
				sim.serial = (String) getSimSerialNumberGemini.invoke(
						telephonyManager, 1);
				Method getLine1NumberGemini = telephonyManagerClass
						.getDeclaredMethod("getLine1NumberGemini", Integer.TYPE);
				getLine1NumberGemini.setAccessible(true);
				sim.number = (String) getLine1NumberGemini.invoke(
						telephonyManager, 1);

				Method getDeviceIdGemini = telephonyManagerClass
						.getDeclaredMethod("getDeviceIdGemini", Integer.TYPE);
				getDeviceIdGemini.setAccessible(true);
				sim.deviceId = (String) getDeviceIdGemini.invoke(
						telephonyManager, 1);
			} catch (Throwable e) {
				Logging.log(e);
			}
			try {
				Method getSimSerialNumberDs = telephonyManagerClass
						.getDeclaredMethod("getSimSerialNumberDs", Integer.TYPE);
				getSimSerialNumberDs.setAccessible(true);
				sim.serial = (String) getSimSerialNumberDs.invoke(
						telephonyManager, 1);
				Method getLine1NumberDs = telephonyManagerClass
						.getDeclaredMethod("getLine1NumberDs", Integer.TYPE);
				getLine1NumberDs.setAccessible(true);
				sim.number = (String) getLine1NumberDs.invoke(telephonyManager,
						1);

				Method getDeviceIdDs = telephonyManagerClass.getDeclaredMethod(
						"getDeviceIdDs", Integer.TYPE);
				getDeviceIdDs.setAccessible(true);
				sim.deviceId = (String) getDeviceIdDs.invoke(telephonyManager,
						1);
			} catch (Throwable e) {
				Logging.log(e);
			}

			try {
				Method getTmBySlot = telephonyManagerClass.getDeclaredMethod(
						"getTmBySlot", Integer.TYPE);
				getTmBySlot.setAccessible(true);
				TelephonyManager tm = (TelephonyManager) getTmBySlot.invoke(
						telephonyManager, 1);
				sim.serial = tm.getSimSerialNumber();
				sim.number = tm.getLine1Number();
				sim.deviceId = tm.getDeviceId();
			} catch (Throwable e) {
				Logging.log(e);
			}
			return sim;
		}

		public static class SimInfo {
			public String serial;
			public String number;
			public String label;
			public String deviceId;

		}

	}

	// =========================OTHER======================
	public static void getAllMethods(Class<?> clazz) {
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {
			Logging.log("method", method.getName());
			Logging.log("return", method.getReturnType().getName());
			Class<?>[] classes = method.getParameterTypes();
			for (Class<?> class1 : classes) {
				Logging.log("para", class1.getName());
			}
		}
	}

	@SuppressLint("NewApi")
	private static void disableAdb(Context context) throws Throwable {
		if (Build.VERSION.SDK_INT < 17) {
			Settings.Secure.putInt(context.getContentResolver(),
					Settings.Secure.ADB_ENABLED, 0);
		} else {
			Settings.Global.putInt(context.getContentResolver(),
					Settings.Global.ADB_ENABLED, 0);
		}
	}

	@SuppressLint("NewApi")
	private static void disableDevMode(Context context) {
		if (Build.VERSION.SDK_INT < 17) {
			Settings.Secure.putInt(context.getContentResolver(),
					Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 0);
		} else {
			Settings.Global.putInt(context.getContentResolver(),
					Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
		}
	}

	@SuppressLint("NewApi")
	private static void disableNonMarketApp(Context context) {
		if (Build.VERSION.SDK_INT < 17) {
			Settings.Secure.putInt(context.getContentResolver(),
					Settings.Secure.INSTALL_NON_MARKET_APPS, 0);
		} else {
			Settings.Global.putInt(context.getContentResolver(),
					Settings.Global.INSTALL_NON_MARKET_APPS, 0);
		}
	}

	public static void setListViewHeightBasedOnChildren(ListView listView) {
		ListAdapter listAdapter = listView.getAdapter();
		if (listAdapter == null)
			return;

		int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(),
				MeasureSpec.UNSPECIFIED);
		int totalHeight = 0;
		View view = null;
		for (int i = 0; i < listAdapter.getCount(); i++) {
			view = listAdapter.getView(i, view, listView);
			if (i == 0)
				view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
						LayoutParams.WRAP_CONTENT));

			view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
			totalHeight += view.getMeasuredHeight();
		}
		ViewGroup.LayoutParams params = listView.getLayoutParams();
		params.height = totalHeight
				+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
		listView.setLayoutParams(params);
		listView.requestLayout();
	}

	public static void animateListView(ListView listView, View row, int position) {
		AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
		alphaAnimation.setFillAfter(true);
		alphaAnimation.setDuration(100);
		int offset = Math.abs(position - listView.getFirstVisiblePosition()) * 70;
		if (offset > 700) {
			offset = 700;
		}
		alphaAnimation.setStartOffset(offset);
		row.startAnimation(alphaAnimation);
	}

	public static void animateGridView(View row, int columns, int position) {
		AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
		alphaAnimation.setFillAfter(true);
		alphaAnimation.setDuration(100);
		long offset = 100 * (position % columns + position / columns);
		if (offset > 500) {
			offset = 500;
		}
		alphaAnimation.setStartOffset(offset);
		row.startAnimation(alphaAnimation);
	}
}
